using System.Data;
using DataScripter.Scripting.InputSources;
using DataScripter.Scripting.Output;
using DataScripter.Scripting.OutputDestinations;
using DataScripter.Scripting.ScriptDefinitions;
using DataScripter.Sorters;

namespace DataScripter.Scripting
{
    class DefaultFullControlOutputProducer : IFullControlOutputProducer
    {
        private readonly IEngine _engine;

        public DefaultFullControlOutputProducer(IEngine engine)
        {
            _engine = engine;
        }

        public IScriptResult Script(ScriptOptions options)
        {
            IInputSource inputSource = _engine.Resolve<IInputSource>();
            inputSource.Initialize();

            IDataProducer dataProducer = inputSource.Resolve<IDataProducer>();

            IOutputDestination outputDestination = _engine.Resolve<IOutputDestination>();
            outputDestination.Initialize();

            IOutputProducer outputProducer = outputDestination.Resolve<IOutputProducer>();

            IScriptResult scriptResult = ScriptResultFactory.CreateScriptResult(options);
            outputProducer.InitializeScript(_engine, scriptResult);

            ISorter<ITableScriptRequest> sorter = _engine.Resolve<ISorter<ITableScriptRequest>>();
            IScriptDefinition scriptDefinition = _engine.Resolve<IScriptDefinition>();

            foreach (ITableScriptRequest tableScriptRequest in sorter.Sort(scriptDefinition.ScriptRequests.Values))
            {
                using (IDataReader reader = dataProducer.ProduceData(tableScriptRequest))
                {
                    outputProducer.ProduceOutput(reader, tableScriptRequest);
                }
            }

            outputProducer.FinalizeScript();
            scriptResult.Close();

            return scriptResult;
        }
    }
}